package gov.pbc.nn.kjgl.jfcr.view;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.entity.ComputerRoom;
import gov.pbc.nn.kjgl.entity.ComputerRoomApplyEntry;
import gov.pbc.nn.kjgl.entity.ComputerRoomArea;
import gov.pbc.nn.kjgl.entity.ComputerRoomEntryType;
import gov.pbc.nn.kjgl.entity.DeviceRecord;
import gov.pbc.nn.kjgl.entity.SignOut;
import gov.pbc.nn.kjgl.jfcr.dao.ApplyEntryDao;
import gov.pbc.nn.uflo.entity.Opinion;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.ProcessService;
import com.bstek.uflo.service.StartProcessInfo;
import com.bstek.uflo.service.TaskOpinion;
import com.bstek.uflo.service.TaskService;

/**
 * 机房进入申请
 * 
 * @author louis
 * 
 */
@Component("applyEntryPR")
public class ApplyEntryPR {

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Autowired
	@Qualifier(TaskService.BEAN_ID)
	private TaskService taskService;

	@Autowired
	@Qualifier(ProcessService.BEAN_ID)
	private ProcessService processService;

	@Autowired
	private ApplyEntryDao applyEntryDao;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;

	/**
	 * 得到所有的带虚拟属性的申请表集合
	 * 
	 * @auther jack.zhao
	 * @return
	 * @throws Exception
	 * 
	 */
	@DataProvider
	public List<ComputerRoomApplyEntry> getAllList() throws Exception {
		List<ComputerRoomApplyEntry> ls = new ArrayList<ComputerRoomApplyEntry>();
		List<ComputerRoomApplyEntry> lists = applyEntryDao.getAllList();
		for (ComputerRoomApplyEntry entity : lists) {
			ComputerRoomApplyEntry targetProduct = EntityUtils.toEntity(entity);
			if (entity.getSignImg() != null) {
				EntityUtils.setValue(targetProduct, "signIn", new String(entity.getSignImg()));
			}
			ls.add(targetProduct);
		}
		return ls;
	}

	/**
	 * 根据id得到一个带有虚拟属性的申请表
	 * 
	 * @auther jack.zhao
	 * @param id
	 * @return
	 * @throws Exception
	 * 
	 */
	@DataProvider
	public ComputerRoomApplyEntry getAll(String id) throws Exception {
		ComputerRoomApplyEntry entity = applyEntryDao.getAll(id);
		ComputerRoomApplyEntry targetProduct = EntityUtils.toEntity(entity);
		if (entity.getSignImg() != null) {
			EntityUtils.setValue(targetProduct, "signIn", new String(entity.getSignImg()));
		}
		EntityUtils.setValue(targetProduct, "devices", this.getDeviceUserById(id));
		EntityUtils.setValue(targetProduct, "signOut", this.getsignOutrById(id));
		return targetProduct;
	}

	public List<DeviceRecord> getDeviceUserById(String id) throws Exception {
		List<DeviceRecord> devices = applyEntryDao.getDevices(id);
		List<DeviceRecord> devss = new ArrayList<DeviceRecord>();
		for (DeviceRecord d : devices) {
			DeviceRecord targetProduct = EntityUtils.toEntity(d);
			EntityUtils.setValue(targetProduct, "user", this.applyEntryDao.getCnameByMamberId(d.getCreateUser()));
			devss.add(targetProduct);
		}
		return devss;
	}

	public List<SignOut> getsignOutrById(String id) throws Exception {
		List<SignOut> ls = new ArrayList<SignOut>();
		if (StringUtils.isEmpty(id)) {
			return new ArrayList<SignOut>();
		} else {
			List<SignOut> lists = applyEntryDao.getSignOutById(id);
			if (lists.size() > 0) {
				for (SignOut s : lists) {
					if (s.getSignImg() != null) {
						SignOut targetProduct = EntityUtils.toEntity(s);
						EntityUtils.setValue(targetProduct, "sign", new String(s.getSignImg()));
						ls.add(targetProduct);
					}
				}
			}
		}
		return ls;
	}

	// public List<SignOut> getsignOutrById(String id) throws Exception {
	// List<SignOut> sigout=applyEntryDao.getsignOuts(id);
	// // List<SignOut> targetsigout = new ArrayList<SignOut>();
	// for (SignOut s : sigout) {
	// s.getSignImg();
	// DeviceRecord targetProduct = EntityUtils.toEntity(s);
	// EntityUtils.setValue(targetProduct, "user",
	// this.applyEntryDao.getCnameByMamberId(d.getCreateUser()));
	// devss.add(targetProduct);
	// }
	//
	// return
	// }

	/**
	 * 自带过滤的但是没有带有虚拟属性的分页查询
	 * 
	 * @auther jack.zhao
	 * @param page
	 * @param criteria
	 * 
	 */
	@DataProvider
	public void getAllPage(Page<ComputerRoomApplyEntry> page, Criteria criteria) {
		applyEntryDao.getPage(page, criteria);
	}

	/**
	 * 根据bussinessId得到该申请
	 * 
	 * @auther jack.zhao
	 * @param bussinessId
	 * @return
	 * @throws Exception
	 * 
	 */
	@DataProvider
	public ComputerRoomApplyEntry loadApply(String bussinessId) throws Exception {
		if (StringUtils.isEmpty(bussinessId)) {
			ComputerRoomApplyEntry computerRoomApplyEntry = new ComputerRoomApplyEntry();
			computerRoomApplyEntry.setTitle("机房出入申请");
			computerRoomApplyEntry.setApplyUserName(ContextHolder.getLoginUser().getCname());
			computerRoomApplyEntry.setApplyDate(new Date());
			computerRoomApplyEntry.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
			computerRoomApplyEntry.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
			return computerRoomApplyEntry;
		} else {
			ComputerRoomApplyEntry entity = applyEntryDao.loadApplyById(bussinessId);
			if (entity.getSignImg() == null) {
				return entity;
			}
			ComputerRoomApplyEntry targetProduct = EntityUtils.toEntity(entity);
			EntityUtils.setValue(targetProduct, "signIn", new String(entity.getSignImg()));
			return targetProduct;
		}
	}

	/**
	 * 
	 * 根据crid得到ComputerRoomArea
	 * 
	 * @auther jack.zhao
	 * @param crid
	 * @return
	 * 
	 */
	@DataProvider
	public List<ComputerRoomArea> geteChildEntityBycrId(String crid) {
		return applyEntryDao.getBycId(crid);
	}

	/**
	 * 得到所有的ComputerRoom
	 * 
	 * @auther jack.zhao
	 * @return
	 */
	@DataProvider
	public List<ComputerRoom> getRooms() {
		return applyEntryDao.getRoom();
	}

	/**
	 * 得到所有的ComputerRoomEntryType
	 * 
	 * @auther jack.zhao
	 * @return
	 */
	@DataProvider
	public List<ComputerRoomEntryType> getTypes() {
		return applyEntryDao.getType();
	}

	/**
	 * 根据parameter得到ComputerRoomArea
	 * 
	 * @auther jack.zhao
	 * @param parameter
	 * @return
	 */
	@DataProvider
	public List<ComputerRoomArea> getAreas(Map<String, Object> parameter) {
		String crId = (String) parameter.get("crId");
		return applyEntryDao.getArea(crId);
	}

	/**
	 * 传入发起流程的身体，保存流程实体，并且发起流程
	 * 
	 * @auther jack.zhao
	 * @param entity
	 */
	@Transactional
	@DataResolver
	public void save(ComputerRoomApplyEntry entity) {
		if (entity != null) {
			try {
				String signIn = EntityUtils.getValue(entity, "signIn");
				if (StringUtils.isNotEmpty(signIn)) {
					entity.setSignImg(signIn.getBytes());
				}
				// 审批执行中。。
				entity.setState(10);
				applyEntryDao.saveAll(entity);
				// 保存外出人员签字
				applyEntryDao.saveSignOutList(entity);

				// 保存设备表的信息
				List<DeviceRecord> lists = EntityUtils.getValue(entity, "devices");
				if (lists != null) {
					if (lists.size() > 0) {
						for (DeviceRecord d : lists) {
							d.setCraeId(entity.getId());
							applyEntryDao.saveDevice(d);
						}
					}
				}
				// 保存处长处理人username，方便以后取出来！
				Map<String, Object> variables = new HashMap<String, Object>();
				// 保存处长和科长的username
				variables.put("kezhangUsername", entity.getKezhangId());
				variables.put("chuzhangUsername", entity.getChuzhangId());

				StartProcessInfo info = new StartProcessInfo();
				info.setPromoter(ContextHolder.getLoginUserName());
				info.setCompleteStartTask(true);
				info.setVariables(variables);
				info.setBusinessId(entity.getId());
				processClient.startProcessByName("机房出入审批", info);

			} catch (Exception e) {
				throw e;
			}
		}
	}

	// @Expose
	// public void startProcess(String bussinessID) {
	// StartProcessInfo info = new StartProcessInfo();
	// info.setPromoter(ContextHolder.getLoginUserName());
	// info.setCompleteStartTask(true);
	// info.setBusinessId(bussinessID);
	// processClient.startProcessById(9, info);
	//
	// }

	/**
	 * 
	 * 关联申请表，并且保存设备表
	 * 
	 * @auther jack.zhao
	 * @param list
	 * @param parameter
	 * 
	 */
	@DataResolver
	@Transactional
	public void saveDevice(List<DeviceRecord> list, Map<String, Object> parameter) {
		if (list.size() > 0) {
			for (DeviceRecord d : list) {
				d.setCraeId((String) parameter.get("craeId"));
				applyEntryDao.saveDevice(d);
			}
		}
	}

	/**
	 * 领导审核的，根据opio判断是通过，还是拒绝，并保存意见表
	 * 
	 * @auther jack.zhao
	 * @param taskId
	 * @param opinion
	 * @param opinionString
	 */
	@Expose
	@Transactional
	public void ajax(String taskId, String opinion, String opinionString, String img, int radiobutton) {
		TaskOpinion option = new TaskOpinion(opinionString);
		Task task = taskClient.getTask(Long.valueOf(taskId));
		long processInstanceId = task.getProcessInstanceId();
		ProcessInstance processInstanc = processClient.getProcessInstanceById(processInstanceId);
		// ProcessDefinition process =
		// processClient.getProcessById(processInstanceId);
		// Integer resutlt = (Integer)
		// processClient.getProcessVariable("result", processInstanc);

		@SuppressWarnings("unchecked")
		List<String> users = (List<String>) processClient.getProcessVariable("shenheren", processInstanc);

		taskClient.start(Long.valueOf(taskId));

		Map<String, Object> map = new HashMap<String, Object>();
		// map.put("agree", "驳回");
		if (opinion.equals("ok")) {
			map.put("agree", "通过");
			map.put(ContextHolder.getLoginUserName(), 1);
		} else {
			System.out.println(ContextHolder.getLoginUserName());
			map.put(ContextHolder.getLoginUserName(), 0);
		}
		if (users.size() == 1) {
			users.remove(ContextHolder.getLoginUserName());
			map.put("shenheren", users);
			map.put(ContextHolder.getLoginUserName(), -1);
		}

		// 把意见保存到意见表中
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setNodeName(task.getNodeName());
		o.setTaskId(Long.parseLong(taskId));
		o.setBusTable("T_COMPUTER_ROOM_APPLY_ENTRY");
		if (radiobutton == 0) {
			o.setOpinion(opinionString);
		} else if (radiobutton == 1) {
			if (StringUtils.isNotEmpty(img)) {
				byte[] bytes = img.getBytes();
				o.setOpinionImg(bytes);
				System.out.println(img);
				System.out.println("=============================================================================");
				System.out.println(new String(bytes));
			}
		}
		// 流程名称。任务名称。deptid，deptname
		// 最新添加的东西没有释放的东西哦
		o.setTaskName(task.getTaskName());
		o.setProcessName("机房出入审批");

		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		// this.applyEntryDao.save(o);
		this.coreHibernateDao.save(o);
		taskClient.complete(Long.valueOf(taskId), map, option);
	}

	/**
	 * 
	 * 最后一个流程的完成
	 * 
	 * @auther jack.zhao
	 * @param taskId
	 * 
	 */
	@Expose
	@Transactional
	public void ajaxConfirm(String taskId) {
		taskClient.start(Long.valueOf(taskId));
		taskClient.complete(Long.valueOf(taskId));
	}

	/**
	 * 
	 * 约定1是通过状态，2是驳回状态；3是个意外状态
	 * 
	 * @auther jack.zhao
	 * @param processInstanceId
	 * @return
	 * 
	 */
	@Expose
	@Transactional
	public int getState(String processInstanceId) {
		ProcessInstance process = processClient.getProcessInstanceById(Long.valueOf(processInstanceId));
		String processVariable = (String) processClient.getProcessVariable("agree", process);
		if (processVariable.equals("通过")) {
			return 1;
		} else if (processVariable.equals("驳回")) {
			return 2;
		}
		return 3;
	}

	/**
	 * 再次申请的实体更新方法！
	 * 
	 * @param entity
	 */
	@DataResolver
	@Transactional
	public void saveUpdateApplyEntry(ComputerRoomApplyEntry entity) {
		if (entity != null) {
			String signIn = EntityUtils.getValue(entity, "signIn");
			if (StringUtils.isNotEmpty(signIn)) {
				entity.setSignImg(signIn.getBytes());
			}
			applyEntryDao.update(entity);
			// 保存外出人员签字
			applyEntryDao.saveSignOutList(entity);

			// 保存设备表的信息
			List<DeviceRecord> lists = EntityUtils.getValue(entity, "devices");
			if (lists != null) {
				if (lists.size() > 0) {
					for (DeviceRecord d : lists) {
						d.setCraeId(entity.getId());
						applyEntryDao.saveDevice(d);
					}
				}
			}
		}
	}

	/**
	 * 申请界面被驳回的时候再次提交申请
	 * 
	 * @param taskId
	 */
	@Expose
	@Transactional
	public void ajaxtj(String taskId) {
		taskClient.start(Long.valueOf(taskId));
		taskClient.complete(Long.valueOf(taskId));
	}

	/**
	 * 结束流程，并保存意见
	 * 
	 * @param taskId
	 * @param opinion
	 */
	@Expose
	@Transactional
	public void ajaxOver(String taskId, String opinion, String img, int radiobutton) {
		TaskOpinion option = new TaskOpinion(opinion);
		Task task = this.taskClient.getTask(Long.parseLong(taskId));
		String busnessId = task.getBusinessId();

		// 更改实体的状态更改为30，30是结束状态
		ComputerRoomApplyEntry computerRoomApplyEntry = this.applyEntryDao.get(busnessId, ComputerRoomApplyEntry.class);
		computerRoomApplyEntry.setState(30);
		this.applyEntryDao.update(computerRoomApplyEntry);
		// 开始流程
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setNodeName(task.getNodeName());
		o.setTaskId(Long.parseLong(taskId));
		o.setBusTable("T_COMPUTER_ROOM_APPLY_ENTRY");
		if (radiobutton == 0) {
			o.setOpinion(opinion);
		} else if (radiobutton == 1) {
			if (StringUtils.isNotEmpty(img)) {
				byte[] bytes = img.getBytes();
				o.setOpinionImg(bytes);
			}
		}
		o.setTaskName(task.getTaskName());
		o.setProcessName("机房出入审批");
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		// this.applyEntryDao.save(o);
		this.coreHibernateDao.save(o);
		this.applyEntryDao.changeState(busnessId);
		// 流程结束，应该根据id删除这个表单
		// this.applyEntryDao.delete(busnessId, ComputerRoomApplyEntry.class);
		taskClient.complete(Long.valueOf(taskId), "结束", option);
	}

	/**
	 * 重修改流程，开始任务，保存意见
	 * 
	 * @param taskId
	 * @param opinion
	 */
	@Expose
	@Transactional
	public void ajaxRe(String taskId, String opinion, String img, int radiobutton) {
		TaskOpinion option = new TaskOpinion(opinion);
		Task task = taskClient.getTask(Long.valueOf(taskId));

		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setNodeName(task.getNodeName());
		o.setBusKey(task.getBusinessId());
		o.setTaskId(Long.parseLong(taskId));
		o.setBusTable("T_COMPUTER_ROOM_APPLY_ENTRY");
		// o.setOpinion(opinion);
		// if (StringUtils.isNotEmpty(img)) {
		// o.setOpinionImg(img.getBytes());
		// }
		if (radiobutton == 0) {
			o.setOpinion(opinion);
		} else if (radiobutton == 1) {
			if (StringUtils.isNotEmpty(img)) {
				byte[] bytes = img.getBytes();
				o.setOpinionImg(bytes);
			}
		}
		o.setTaskName(task.getTaskName());
		o.setProcessName("机房出入审批");
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		// this.applyEntryDao.save(o);
		this.coreHibernateDao.save(o);

		taskClient.complete(Long.valueOf(taskId), "重修改", option);
	}

	/**
	 * 再提交，把任务给机房管理员
	 * 
	 * @param taskId
	 */
	@Expose
	@Transactional
	public void ajaxReTj(String taskId) {
		taskClient.start(Long.valueOf(taskId));
		taskClient.complete(Long.valueOf(taskId));
	}

	/**
	 * 根据id得到设备表
	 * 
	 * @param id
	 * @return
	 */
	@DataProvider
	public List<DeviceRecord> getDeviceById(String id) {
		return applyEntryDao.getDevices(id);
	}

	/**
	 * 在修改的跟新申请表和设备表
	 * 
	 * @param entity
	 * @param lists
	 * @throws Exception
	 */
	@DataResolver
	@Transactional
	public void saveAll(ComputerRoomApplyEntry entity) throws Exception {
		if (entity != null) {
			String signIn = EntityUtils.getValue(entity, "signIn");
			if (StringUtils.isNotEmpty(signIn)) {
				entity.setSignImg(signIn.getBytes());
			}
			applyEntryDao.update(entity);
		}
		// 設備表
		List<DeviceRecord> lists = EntityUtils.getValue(entity, "devices");
		if (lists.size() > 0) {
			for (DeviceRecord d : lists) {
				d.setCraeId(entity.getId());
				applyEntryDao.saveDevice(d);
			}
		}
		// 更新簽名表
		List<SignOut> ls = EntityUtils.getValue(entity, "signOut");
		for (SignOut sigOut : ls) {
			String sign = EntityUtils.getValue(sigOut, "sign");
			sigOut.setApplyId(entity.getId());
			if (StringUtils.isNotEmpty(sign)) {
				sigOut.setSignImg(sign.getBytes());
			}
			this.applyEntryDao.saveSigOut(sigOut);
		}

	}

	/**
	 * 根据id得到外来人员签名的图片
	 * 
	 * @auther jack.zhao
	 * @param id
	 * @return
	 * @throws Exception
	 * 
	 */
	@DataProvider
	public List<SignOut> getSignOuts(String id) throws Exception {
		List<SignOut> ls = new ArrayList<SignOut>();
		if (StringUtils.isEmpty(id)) {
			return new ArrayList<SignOut>();
		} else {
			List<SignOut> lists = applyEntryDao.getSignOutById(id);
			if (lists.size() > 0) {
				for (SignOut s : lists) {
					if (s.getSignImg() != null) {
						SignOut targetProduct = EntityUtils.toEntity(s);
						EntityUtils.setValue(targetProduct, "sign", new String(s.getSignImg()));
						ls.add(targetProduct);
					}
				}
			}
		}
		return ls;
	}

	/**
	 * 撤销流程的操作
	 * 
	 * @auther jack.zhao
	 * @param taskId
	 * 
	 */
	@Expose
	@Transactional
	public void cancelSq(String taskId) {
		Task task = taskClient.getTask(Long.valueOf(taskId));
		String busnessId = task.getBusinessId();
		ComputerRoomApplyEntry computerRoomApplyEntry = this.applyEntryDao.get(busnessId, ComputerRoomApplyEntry.class);
		computerRoomApplyEntry.setState(20);
		this.applyEntryDao.update(computerRoomApplyEntry);
		// 完成任务
		taskClient.start(Long.valueOf(taskId));
		taskClient.forward(Long.valueOf(taskId), "结束");
	}

	/**
	 * 科长的下拉列表！
	 * 
	 * @auther jack.zhao
	 * @return
	 * 
	 */
	@DataProvider
	public List<IUser> getkezhangs() {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(), Constants.ROLE_KZ);
		return users;
	}

	/**
	 * 科长的下拉列表！
	 * 
	 * @auther jack.zhao
	 * @return
	 * 
	 */
	@DataProvider
	public List<IUser> getchuzhangs() {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(), Constants.ROLE_CZ);
		return users;
	}

	/**
	 * 
	 * 
	 * @auther jack.zhao
	 * @param id
	 * 
	 */
	@Expose
	@Transactional
	public void deleteDeviceById(String id) {
		this.applyEntryDao.delete(id, DeviceRecord.class);
	}
}
